package com.sjp.demo.rpc.provider;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class RpcServer implements ApplicationContextAware, InitializingBean {

    private ExecutorService executorService = Executors.newCachedThreadPool();
    private Map<String, Object> serviceMap = new HashMap<>();

    private int port;

    public RpcServer(int port) {
        this.port = port;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(RpcService.class);
        for (Object serviceBean : beans.values()) {
            RpcService annotation = serviceBean.getClass().getAnnotation(RpcService.class);
            String serviceName = annotation.value().getName();
            String version = annotation.version();
            if (!StringUtils.isEmpty(version)) {
                serviceName += version;
            }
            serviceMap.put(serviceName, serviceBean);
        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            while (true) {//不断接收请求
                System.out.println("等待请求……");
                Socket accept = serverSocket.accept();
                executorService.execute(new ProcessorHandler(accept, serviceMap));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
